package com.atguigu.c_designed.m1createModel.c3prototype.deepClone;

/**
 * 原型模式： 是 创建型 设计模式之一，该模式的思想就是将一个对象作为原型，对其进行复制、克隆，产生一个和原对象相似的新对象。
 * 性能优良，Java自带的 原型模式 是基于内存二进制流的拷贝，比直接new一个对象性能上提升了许多。
 * 可以使用深克隆方式保存对象的状态，使用原型模式将对象复制一份并将其状态保存起来，以便在需要的时候使用(例如恢复到历史某一状态)，可辅助实现撤销操作。
 */

/**
 * 浅克隆：clone对象依赖其他引用对象的时候，clone出来的对象里面的引用对象会跟着引用对象的变化而变化，并不是独立的
 * 深克隆：clone对象依赖其他引用对象的时候，clone出来的引用对象是独立的 实现引用对象的克隆方法
 */
// 客户端
public class Client {
    public static void main(String[] args) {
        //创建原型对象
        ConcretePrototype type = new ConcretePrototype("original");
        B b = new B("qwe", "22");
        type.b = b;
        //拷贝原型对象
        ConcretePrototype cloneType = type.clone();
        B b1 = cloneType.b;
        b1.setName("aa");

        System.out.println(type+","+type.hashCode()+","+type.b.hashCode());
        System.out.println(cloneType+","+cloneType.hashCode()+","+cloneType.b.hashCode());
    }
}



//具体原型
class ConcretePrototype implements Cloneable {
    B b;
    String desc;

    public ConcretePrototype(String desc) {
        this.desc = desc;
    }

    @Override
    protected ConcretePrototype clone() {
        ConcretePrototype cloneType = null;
        try {
            cloneType = (ConcretePrototype) super.clone();
            cloneType.b = (B) b.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return cloneType;
    }

    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "b=" + b +
                ", desc='" + desc + '\'' +
                '}';
    }
}

class B implements Cloneable {

    private String name;
    private String age;

    public B(String name, String age) {
        this.name = name;
        this.age =age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "B{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return (B)super.clone();
    }
}